Springboot整合Poi导出excel(简单版)

您所在的位置:网站首页 spring boot 文件导出 Springboot整合Poi导出excel(简单版)

Springboot整合Poi导出excel(简单版)

2023-07-21 22:24| 来源: 网络整理| 查看: 265

一. 问题引入

博客专栏:

Springboot整合Poi导出excel(简单版)

Springboot整合Poi导出excel(注解版)

总所周知Springboot是一个功能强大的微服务框架,集成了很多优秀的Spring组件,但是却没有支持Excel导出的插件。为此我们引入Poi插件。场景是导出Controller返回的Json数据,输出到二维表格。设置表头及其他设置可参考Poi中文文档。本教程试用简单导出Excel,通俗易懂。

1. 首先从中央仓库中导入架包Poi3.14以及Poi-ooxml3.14. org.apache.poi poi 3.14 org.apache.poi poi-ooxml 3.14 2.编写工具类

编写用于导出Excel的工具类ExportExcelUtils,工具类可以直接使用,不需要更改。

package org.emall.website.util; import org.apache.poi.hssf.usermodel.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.util.Date; import java.text.SimpleDateFormat; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * @author created by Zhangdazhuang * @version v.0.1 * @Description TODO * @date 2019/4/7 * @备注 **/ public class ExportExcelUtils { private static final Logger logger = LoggerFactory.getLogger(ExportExcelUtils.class); /** * 导出Excel * * @param excelName 要导出的excel名称 * @param list 要导出的数据集合 * @param fieldMap 中英文字段对应Map,即要导出的excel表头 * @param response 使用response可以导出到浏览器 * @param */ public static void export(String excelName, List list, LinkedHashMap fieldMap, HttpServletResponse response) { // 设置默认文件名为当前时间:年月日时分秒 if (excelName == null || excelName == "") { excelName = new SimpleDateFormat("yyyyMMddhhmmss").format( new Date()).toString(); } // 设置response头信息 response.reset(); response.setContentType("application/vnd.ms-excel"); // 改成输出excel文件 try { response.setHeader("Content-disposition", "attachment; filename=" + new String(excelName.getBytes("gb2312"), "ISO-8859-1") + ".xls"); } catch (UnsupportedEncodingException e1) { logger.info(e1.getMessage()); } try { //创建一个WorkBook,对应一个Excel文件 HSSFWorkbook wb = new HSSFWorkbook(); //在Workbook中,创建一个sheet,对应Excel中的工作薄(sheet) HSSFSheet sheet = wb.createSheet(excelName); //创建单元格,并设置值表头 设置表头居中 HSSFCellStyle style = wb.createCellStyle(); //创建一个居中格式 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 填充工作表 fillSheet(sheet, list, fieldMap, style); //将文件输出 OutputStream ouputStream = response.getOutputStream(); wb.write(ouputStream); ouputStream.flush(); ouputStream.close(); } catch (Exception e) { logger.info("导出Excel失败!"); logger.error(e.getMessage()); } } /** * 根据字段名获取字段对象 * * @param fieldName 字段名 * @param clazz 包含该字段的类 * @return 字段 */ public static Field getFieldByName(String fieldName, Class clazz) { logger.info("根据字段名获取字段对象:getFieldByName()"); // 拿到本类的所有字段 Field[] selfFields = clazz.getDeclaredFields(); // 如果本类中存在该字段,则返回 for (Field field : selfFields) { //如果本类中存在该字段,则返回 if (field.getName().equals(fieldName)) { return field; } } // 否则,查看父类中是否存在此字段,如果有则返回 Class superClazz = clazz.getSuperclass(); if (superClazz != null && superClazz != Object.class) { //递归 return getFieldByName(fieldName, superClazz); } // 如果本类和父类都没有,则返回空 return null; } /** * 根据字段名获取字段值 * * @param fieldName 字段名 * @param o 对象 * @return 字段值 * @throws Exception 异常 */ public static Object getFieldValueByName(String fieldName, Object o) throws Exception { logger.info("根据字段名获取字段值:getFieldValueByName()"); Object value = null; //根据字段名得到字段对象 Field field = getFieldByName(fieldName, o.getClass()); //如果该字段存在,则取出该字段的值 if (field != null) { field.setAccessible(true);//类中的成员变量为private,在类外边使用属性值,故必须进行此操作 value = field.get(o);//获取当前对象中当前Field的value } else { throw new Exception(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName); } return value; } /** * 根据带路径或不带路径的属性名获取属性值,即接受简单属性名, * 如userName等,又接受带路径的属性名,如student.department.name等 * * @param fieldNameSequence 带路径的属性名或简单属性名 * @param o 对象 * @return 属性值 * @throws Exception 异常 */ public static Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception { logger.info("根据带路径或不带路径的属性名获取属性值,即接受简单属性名:getFieldValueByNameSequence()"); Object value = null; // 将fieldNameSequence进行拆分 String[] attributes = fieldNameSequence.split("\\."); if (attributes.length == 1) { value = getFieldValueByName(fieldNameSequence, o); } else { // 根据数组中第一个连接属性名获取连接属性对象,如student.department.name Object fieldObj = getFieldValueByName(attributes[0], o); //截取除第一个属性名之后的路径 String subFieldNameSequence = fieldNameSequence .substring(fieldNameSequence.indexOf(".") + 1); //递归得到最终的属性对象的值 value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj); } return value; } /** * 向工作表中填充数据 * * @param sheet excel的工作表名称 * @param list 数据源 * @param fieldMap 中英文字段对应关系的Map * @param style 表格中的格式 * @throws Exception 异常 */ public static void fillSheet(HSSFSheet sheet, List list, LinkedHashMap fieldMap, HSSFCellStyle style) throws Exception { logger.info("向工作表中填充数据:fillSheet()"); // 定义存放英文字段名和中文字段名的数组 String[] enFields = new String[fieldMap.size()]; String[] cnFields = new String[fieldMap.size()]; // 填充数组 int count = 0; for (Map.Entry entry : fieldMap.entrySet()) { enFields[count] = entry.getKey(); cnFields[count] = entry.getValue(); count++; } //在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short HSSFRow row = sheet.createRow((int) 0); // 填充表头 for (int i = 0; i < cnFields.length; i++) { HSSFCell cell = row.createCell(i); cell.setCellValue(cnFields[i]); cell.setCellStyle(style); sheet.autoSizeColumn(i); } // 填充内容 for (int index = 0; index < list.size(); index++) { row = sheet.createRow(index + 1); // 获取单个对象 T item = list.get(index); for (int i = 0; i < enFields.length; i++) { Object objValue = getFieldValueByNameSequence(enFields[i], item); String fieldValue = objValue == null ? "" : objValue.toString(); row.createCell(i).setCellValue(fieldValue); } } } } 3.编写实体类

需要输出到Excel的实体表。

package org.emall.website.entity; import java.math.BigInteger; /** * @author created by Zhangdazhuang * @version v.0.1 * @Description TODO * @date 2019/4/7 * @备注 **/ public class Excel { private BigInteger id; private String order_number; private String amount_real; private String date_add; private String status_str; private String link_man; private String mobie; private String address; private String detailValue; public Excel() { } public Excel(BigInteger id, String order_number, String amount_real, String date_add, String status_str, String link_man, String mobie, String address, String detailValue) { this.id = id; this.order_number = order_number; this.amount_real = amount_real; this.date_add = date_add; this.status_str = status_str; this.link_man = link_man; this.mobie = mobie; this.address = address; this.detailValue = detailValue; } public BigInteger getId() { return id; } public void setId(BigInteger id) { this.id = id; } public String getOrder_number() { return order_number; } public void setOrder_number(String order_number) { this.order_number = order_number; } public String getAmount_real() { return amount_real; } public void setAmount_real(String amount_real) { this.amount_real = amount_real; } public String getDate_add() { return date_add; } public void setDate_add(String date_add) { this.date_add = date_add; } public String getStatus_str() { return status_str; } public void setStatus_str(String status_str) { this.status_str = status_str; } public String getLink_man() { return link_man; } public void setLink_man(String link_man) { this.link_man = link_man; } public String getMobie() { return mobie; } public void setMobie(String mobie) { this.mobie = mobie; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getDetailValue() { return detailValue; } public void setDetailValue(String detailValue) { this.detailValue = detailValue; } } 4.编写控制层即得到Json数据

编写控制层ExcelController,注意fieldMap.put(“实体类属性名”,“Excel中显示的属性名”); 设置实体属性名和数据库中对应。如果得不到数据对应不上,请采用ResultMap设置或者用Select XX(数据库名)As 实体属性名。

package org.emall.website.controller; import org.emall.website.entity.Excel; import org.emall.website.entity.Order; import org.emall.website.service.OrderService; import org.emall.website.util.ExportExcelUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.LinkedHashMap; import java.util.List; /** * @author created by Zhangdazhuang * @version v.0.1 * @Description TODO * @date 2019/4/7 * @备注 **/ @Controller public class ExcelController { @Autowired private HttpServletRequest request; @Autowired private OrderService orderService; @RequestMapping(value = "/excel/exportBankCheckInfo",method = RequestMethod.GET) public void ExportBankCkeckInfo(HttpServletResponse response, HttpServletRequest request){ //这里是笔者实际业务需求中需要得到时间间隔。可忽略 String start=request.getParameter("start"); String end=request.getParameter("end"); System.out.println("打印的起始日期为:"+start+",打印的结束日期为:"+end); //得到所有要导出的数据 List orderlist =orderService.listexcel(start,end); //定义导出的excel名字 String excelName = "订单详情表"; //获取需要转出的excel表头的map字段 LinkedHashMap fieldMap = new LinkedHashMap(); fieldMap.put("id","编号"); fieldMap.put("link_man","姓名"); fieldMap.put("amount_real","价格"); fieldMap.put("date_add","日期"); fieldMap.put("status_str","订单状态"); fieldMap.put("mobie","收货电话"); fieldMap.put("address","地址"); fieldMap.put("detailValue","订单详情"); //导出用户相关信息 new ExportExcelUtils().export(excelName,orderlist,fieldMap,response); } } 5.验证

在导出工具类中,通过HttpServletResponse response设置输出为Excel。所以通过Controller层的Url可以直接得到URL。保存位置是保存在浏览器的默认保存位置,因为是下载请求。(笔者存疑:是否可以保存到任意位置)。 输入请求 127.0.0.1:8080/(可选项目名)/excel/exportBankCheckInfo

最后查看导出的Excel格式如下: 在这里插入图片描述 这里只是简单实现了Excel的导入,通过Poi插件或者其他开源的插件可以对导入导出Excel做更加功能丰富的操作,详情请移步CSDN或者github。欢迎加入Q群959706394,大家一起学习交流编程知识,解决实际业务需求中各种需求。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3